﻿@namespace MudBlazor.Docs.Examples
@using MudBlazor.Utilities

<div class="d-flex flex-column mud-width-full mud-height-full">
	<MudToolBar Class="gap-4">
		<MudButton OnClick="LoadServerData" Variant="Variant.Filled" Color="Color.Default">Load Data</MudButton>
		<MudButton OnClick="SaveData" Variant="Variant.Filled" Color="Color.Primary">Save Data</MudButton>
		<MudSpacer />
		<MudButton OnClick="Reset" Variant="Variant.Text" Color="Color.Error">Reset Example</MudButton>
	</MudToolBar>

	<MudDropContainer T="DropItem" Items="@_dropzoneItems" @ref="_container" ItemsSelector="@((item,dropzone) => item.Selector == dropzone)" ItemDropped="ItemUpdated" Class="d-flex flex-wrap flex-grow-1">
		<ChildContent>
			@for (int i = 1; i < 3; i++)
			{
				var dropzone = i.ToString();
				<MudPaper Class="ma-4 flex-grow-1">
                    <MudList T="string" Class="d-flex flex-column mud-height-full">
						<MudListSubheader>Drop Zone @dropzone</MudListSubheader>
						<MudDropZone T="DropItem" Identifier="@dropzone" Class="flex-grow-1" AllowReorder="true" />
					</MudList>
				</MudPaper>
			}
		</ChildContent>
		<ItemRenderer>
            <MudListItem T="string" Text="@($"{context.Name} ({context.Order})")" />
		</ItemRenderer>
	</MudDropContainer>
</div>
@code {
    private MudDropContainer<DropItem> _container;

	private void ItemUpdated(MudItemDropInfo<DropItem> dropItem)
	{
		dropItem.Item.Selector = dropItem.DropzoneIdentifier;

		var indexOffset = dropItem.DropzoneIdentifier switch
		{
			"2"  => _dropzoneItems.Count(x => x.Selector == "1"),
			_ => 0
		};

		_dropzoneItems.UpdateOrder(dropItem, item => item.Order, indexOffset);
	}

	private List<DropItem> _dropzoneItems = new();

	private List<DropItem> _serverData = new()
		{
			new DropItem() { Order = 0, Name = "Item 1", Selector = "1" },
			new DropItem() { Order = 1, Name = "Item 2", Selector = "1" },
			new DropItem() { Order = 2, Name = "Item 3", Selector = "1" },
			new DropItem() { Order = 3, Name = "Item 4", Selector = "1" },
			new DropItem() { Order = 4, Name = "Item 5", Selector = "1" },
			new DropItem() { Order = 5, Name = "Item 6", Selector = "1" },
			new DropItem() { Order = 6, Name = "Item 7", Selector = "2" },
			new DropItem() { Order = 7, Name = "Item 8", Selector = "2" },
			new DropItem() { Order = 8, Name = "Item 9", Selector = "2" },
			new DropItem() { Order = 9, Name = "Item 10", Selector = "2" },
		};

	private void RefreshContainer()
	{
		//update the binding to the container
		StateHasChanged();

		//the container refreshes the internal state
		_container.Refresh();
	}

	private void LoadServerData()
	{
	    _dropzoneItems = _serverData
	        .OrderBy(x => x.Order)
	        .Select(item => new DropItem
	        {
	            Order = item.Order,
	            Name = item.Name,
	            Selector = item.Selector
	        })
	        .ToList();
		RefreshContainer();
	}

	private void SaveData()
	    => _serverData = _dropzoneItems
	        .OrderBy(x => x.Order)
	        .Select(item => new DropItem
	        {
	            Order = item.Order, Name = item.Name, Selector = item.Selector
	        })
	        .ToList();

	private void Reset()
	{
		_dropzoneItems = new();
		_serverData = new()
			{
				new DropItem() { Order = 0, Name = "Item 1", Selector = "1" },
				new DropItem() { Order = 1, Name = "Item 2", Selector = "1" },
				new DropItem() { Order = 2, Name = "Item 3", Selector = "1" },
				new DropItem() { Order = 3, Name = "Item 4", Selector = "1" },
				new DropItem() { Order = 4, Name = "Item 5", Selector = "1" },
				new DropItem() { Order = 5, Name = "Item 6", Selector = "1" },
				new DropItem() { Order = 6, Name = "Item 7", Selector = "2" },
				new DropItem() { Order = 7, Name = "Item 8", Selector = "2" },
				new DropItem() { Order = 8, Name = "Item 9", Selector = "2" },
				new DropItem() { Order = 9, Name = "Item 10", Selector = "2" }
			};

		RefreshContainer();
	}
    
    public class DropItem
    {
        public string Name { get; init; }
        public string Selector { get; set; }
        public int Order { get; set; }
    }
}
